package com.topnav.mc.admin.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.js.lib.cache.Cache;
import com.topnav.mc.admin.dao.mapper.DeviceAlarmMapper;
import com.topnav.mc.admin.dao.mapper.OrganizationMapper;
import com.topnav.mc.admin.entity.*;
import com.topnav.mc.admin.entity.bean.LogContentBean;
import com.topnav.mc.admin.entity.bean.UserBean;
import com.topnav.mc.admin.entity.enums.EnumLogType;
import com.topnav.mc.admin.entity.enums.EnumOperateFunction;
import com.topnav.mc.admin.entity.param.UserParam;
import com.topnav.mc.admin.service.*;
import com.topnav.mc.base.mc.McServiceImpl;
import com.topnav.mc.common.Constant;
import com.topnav.mc.document.entity.Document;
import com.topnav.mc.document.service.IDocumentService;
import com.topnav.mc.exception.ExceptionMsg;
import com.topnav.mc.uitls.ExceptionUtil;
import com.topnav.mc.uitls.PasswordUtil;
import com.topnav.mc.uitls.PermissionGradeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.toolkit.SqlHelper;
import com.js.lib.exception.CustomException;
import com.topnav.mc.admin.dao.mapper.UserMapper;

import javax.annotation.Resource;
import static com.topnav.mc.exception.ExceptionMsg.*;
/**
 * 说明：操作员CURD管理
 * @类名: UserServiceImpl
 * <p>
 *
 * </p>
 * @author   kenny
 * @Date	 2021年11月19日下午6:00:29
 */
@Service
//public class UserServiceImpl extends CommServiceImpl<UserMapper,User> implements IUserService{
public class UserServiceImpl extends McServiceImpl<UserMapper,User, UserBean, UserParam> implements IUserService{
	@Autowired
	private OrganizationMapper organizationMapper;
	@Autowired
	private IUserRoleService userRoleService;
	//@Resource
	@Autowired
	private PasswordEncoder passwordEncoder;
	@Autowired
	private IRoleService roleService;
	@Autowired
	private IUserOrganizaitonService userOrganizaitonService;
	@Autowired
	private IDocumentService documentService;
	@Autowired
	private IDeviceAlarmService deviceAlarmService;
	@Autowired
	private IDeviceFavoriteService deviceFavoriteService;
	@Autowired
	private IOperateLogService operateLogService;
	@Resource
	private PermissionGradeUtil permissionGradeUtil;
	@Resource(name="sysCache")
	private Cache sysCache;

	@Override
	public  boolean beforeDelete(User entity){
		//用户文件
		LambdaQueryWrapper<Document> documentWrapper = new LambdaQueryWrapper<>();
		documentWrapper.eq(Document::getUserId,entity.getId());
		if (documentService.getOne(documentWrapper,false) != null){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_BY_DOCUMENT);
		}

		if (entity.getId().equals(permissionGradeUtil.getPmGradeCheck().getUserId())){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_BY_SELF);
		}

		/*//用户部门权限
		LambdaQueryWrapper<UserOrganizaiton> userOrganizaitonWrapper = new LambdaQueryWrapper<>();
		userOrganizaitonWrapper.eq(UserOrganizaiton::getUserId,entity.getId());
		if (userOrganizaitonService.getOne(userOrganizaitonWrapper,false) != null){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_BY_ORGANIZATION);
		}

		//用户角色
		LambdaQueryWrapper<UserRole> userRoleWrapper = new LambdaQueryWrapper<>();
		userRoleWrapper.eq(UserRole::getUserId,entity.getId());
		if (userRoleService.getOne(userRoleWrapper,false) != null){
			//throw new CustomException(-1,"此用户已分配角色权限，请先解除角色绑定，再删除");
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_BY_ROLE);
		}

		//设备报警处置
		LambdaQueryWrapper<DeviceAlarm> deviceAlarmWrapper = new LambdaQueryWrapper<>();
		deviceAlarmWrapper.eq(DeviceAlarm::getDisposeUserId,entity.getId());
		if (deviceAlarmService.getOne(deviceAlarmWrapper,false) != null){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_DEVICEALARM);
		}

		//设备收藏
		LambdaQueryWrapper<DeviceFavorite> deviceFavoriteWrapper = new LambdaQueryWrapper<>();
		deviceFavoriteWrapper.eq(DeviceFavorite::getUserId,entity.getId());
		if (deviceFavoriteService.getOne(deviceFavoriteWrapper,false) != null){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_FAVOREITE);
		}

		LambdaQueryWrapper<OperateLog> operateLogWrapper = new LambdaQueryWrapper<>();
		operateLogWrapper.eq(OperateLog::getUserId,entity.getId());
		if (operateLogService.getOne(operateLogWrapper,false) != null){
			throw ExceptionUtil.commonException(ExceptionMsg.ERROR_DELETE_USER_USED_FAVOREITE);
		}*/

		return true;
	}
	@Override
	public void afterDelete(User entity){
		operateLogService.saveLog(EnumLogType.DELETE, EnumOperateFunction.USER,new LogContentBean().setCode(entity.getLoginName()).setName(entity.getName()));
		this.removeFromCache(entity.getCode());
	}
	@Override
	public void afterSave(User entity){
		/** 添加 角色*/
		if (!CollectionUtils.isEmpty(entity.getRoles())){
			List<UserRole> batch = new ArrayList<>();
			for(Role r: entity.getRoles()){
				UserRole ur = new UserRole();
				ur.setUserId(entity.getId());
				ur.setRoleId(r.getId());
				ur.setCreateTime(new Date());
				ur.setUpdateTime(new Date());
				batch.add(ur);
			}
			userRoleService.saveBatch(batch);
		}
		/** 同时增加或修改用户单位权限表 */
		this.updateUserOrganization(entity);
		operateLogService.saveLog(EnumLogType.ADD, EnumOperateFunction.USER,new LogContentBean().setCode(entity.getLoginName()).setName(entity.getName()));
	}
	@Override
	public void afterUpdate(User entity){
		/** 添加 角色*/

		/** 先删除旧数据 */
		QueryWrapper<UserRole> wrapper1 = new QueryWrapper<UserRole>().eq("user_id", entity.getId());
		userRoleService.remove(wrapper1);
		/** 再添加新数据 */
		if (!CollectionUtils.isEmpty(entity.getRoles())){
			List<UserRole> batch = new ArrayList<>();
			for(Role r: entity.getRoles()){
				UserRole ur = new UserRole();
				ur.setUserId(entity.getId());
				ur.setRoleId(r.getId());
				ur.setCreateTime(new Date());
				ur.setUpdateTime(new Date());
				batch.add(ur);
			}
			userRoleService.saveBatch(batch);
		}

		/** 同时增加或修改用户单位权限表 */
		updateUserOrganization(entity);
		operateLogService.saveLog(EnumLogType.EDIT, EnumOperateFunction.USER,new LogContentBean().setCode(entity.getLoginName()).setName(entity.getName()));
	}

	@Override
	public boolean beforeSave(User entity){
		if (this.getOne(new QueryWrapper<User>().eq("login_name",entity.getLoginName()), true) != null){
			throw ExceptionUtil.commonException(ERROR_PARAM_ACCOUNT_EXISTS);
		}
		if (StringUtils.isEmpty(entity.getPassword())){
			entity.setPassword("88888888");
		}

		if (StringUtils.isEmpty(entity.getLoginName())){
			entity.setLoginName(entity.getCode());
		}
		entity.setPassword(PasswordUtil.genPassword(entity.getPassword()));
		entity.setEnabledNotify(true);
		entity.setCreateTime(new Date());
		entity.setUpdateTime(new Date());
		return true;
	}
	@Override
	public boolean beforeUpdate(User entity){
		QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("login_name", entity.getLoginName()).ne("id", entity.getId());
		if (this.getOne(wrapper, true) != null){
			throw ExceptionUtil.commonException(ERROR_PARAM_ACCOUNT_EXISTS);
		}
		/** 更新 */
		entity.setUpdateTime(new Date());
		return true;
	}

	/**
	 * 删除相关联
	 * 设备报警/设备日志设备收藏/用户单位/用户角色
	 * @param entity
	 */
	@Override
	public void removeRelate(User entity){
/*
		*/
/** 先删除角色*//*

		QueryWrapper<UserRole> wrapper1 = new QueryWrapper<UserRole>().eq("user_id", queryWrapper.getEntity().getId());
		userRoleService.remove(wrapper1);

		*/
/** 删除用户单位权限表 *//*

		QueryWrapper<UserOrganizaiton> wrapper = new QueryWrapper<UserOrganizaiton>().eq("user_id",queryWrapper.getEntity().getId());
		userOrganizaitonService.remove(wrapper);

		*/
/** 删除设备收藏表 *//*

		LambdaQueryWrapper<DeviceFavorite> dfQueryWrapper = new LambdaQueryWrapper<DeviceFavorite>().eq(DeviceFavorite::getUserId,queryWrapper.getEntity().getId());
		deviceFavoriteService.remove(dfQueryWrapper);
*/

		//1、设备报警
		LambdaQueryWrapper<DeviceAlarm> alarmWrapper = new LambdaQueryWrapper<>();
		alarmWrapper.eq(DeviceAlarm::getDisposeUserId,entity.getId());
		deviceAlarmService.remove(alarmWrapper);

		//2、设备收藏
		LambdaQueryWrapper<DeviceFavorite> favoriteWrapper = new LambdaQueryWrapper<>();
		favoriteWrapper.eq(DeviceFavorite::getUserId,entity.getId());
		deviceFavoriteService.remove(favoriteWrapper);

		//3、操作日志
		LambdaQueryWrapper<OperateLog> logWrapper = new LambdaQueryWrapper<>();
		logWrapper.eq(OperateLog::getUserId,entity.getId());
		operateLogService.remove(logWrapper);
		//4、机构用户
		LambdaQueryWrapper<UserOrganizaiton> ugWrapper = new LambdaQueryWrapper<>();
		ugWrapper.eq(UserOrganizaiton::getUserId,entity.getId());
		userOrganizaitonService.remove(ugWrapper);

		//5、用户角色
		LambdaQueryWrapper<UserRole> urWrapper = new LambdaQueryWrapper<>();
		urWrapper.eq(UserRole::getUserId,entity.getId());
		userRoleService.remove(urWrapper);
	}


	@Override
	/**
	 * 允许 接收通知
	 * @param user
	 * @param enabledNotify
	 */
	public void enabledNotify(User user,Boolean enabledNotify){

	}


	@Override
	@Transactional
	public boolean save(User entity) {
		boolean result = super.save(entity);
		if (result)
			this.saveToCache(entity);
		return result;
	}



	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean updateById(User entity) {
		boolean result = super.updateById(entity);
		if (result)
			this.saveToCache(entity);
		return result;
	}

	/**
	 * 新增或修改用户时
	 * 同时增加或修改用户单位权限表
	 * @param entity
	 */
	public void updateUserOrganization(User entity){
		if (entity.getOrgId()!= null){
			/** 取得最大权限 的Role */
			Role role = roleService.getOneHighLevelByUserRole(entity.getId());
			QueryWrapper<UserOrganizaiton> wrapper = new QueryWrapper<UserOrganizaiton>().eq("user_id",entity.getId()).eq("org_id",entity.getOrgId());
			UserOrganizaiton userOrganizaiton = userOrganizaitonService.getOne(wrapper,false);
			if (userOrganizaiton == null){
				userOrganizaiton = new UserOrganizaiton();
				userOrganizaiton.setUserId(entity.getId());
				userOrganizaiton.setOrgId(entity.getOrgId());
				userOrganizaiton.setCreateTime(new Date());
			}
			if (role != null){
				userOrganizaiton.setRoleId(role.getId());
			}
			userOrganizaiton.setUpdateTime(new Date());
			userOrganizaitonService.saveOrUpdate(userOrganizaiton);
		}
	}

	@Override
	public List<User> list(Wrapper<User> queryWrapper) {
		List<User> list = getBaseMapper().selectList(queryWrapper);
		/** 单位 */
		List<User> resultList = getExtentProp(list);
		return list;

	}

    /**
     * 翻页查询
     *
     * @param page         翻页对象
     * @param queryWrapper 实体对象封装操作类 {@link com.baomidou.mybatisplus.core.conditions.query.QueryWrapper}
     */
	@Override
	public <E extends IPage<User>> E page(E page, Wrapper<User> queryWrapper) {
		E e = getBaseMapper().selectPage(page, queryWrapper);
		e.setRecords(getExtentProp(e.getRecords()));
		return e;
    }

	/**
	 * 修改密码
	 * @param userParam
	 * @return
	 */
	@Override
	public boolean changePassword(UserParam userParam) {
		if (userParam == null){
			throw new CustomException(-1,"参数必须提供");
		}

		if(StringUtils.isEmpty(userParam.getUserCode())){
			throw new CustomException(-1,"用户编号必须提供");
		}
		/** 新密码必须提供  */
		if(StringUtils.isEmpty(userParam.getOldPassword())){
			throw ExceptionUtil.commonException(ERROR_AUTHENTICATION_NEW_PASSWORD_LOSE);
		}
		/** 确认密码必须提供  */
		if(StringUtils.isEmpty(userParam.getNewPassword())){
			throw ExceptionUtil.commonException(ERROR_AUTHENTICATION_CONFIRM_PASSWORD_LOSE);
		}
		QueryWrapper<User> wrapper = new QueryWrapper<User>();
		wrapper.eq("login_name",userParam.getUserCode() );
		User user = this.getOne(wrapper, false);
		if (user == null){
			//throw new CustomException(-1,"不存在的用户【'+userParam.getUserCode()+'】");
			throw ExceptionUtil.commonException(ERROR_AUTHENTICATION_NOT_EXISTS_USER);
		}
		/** 确认密码不一致 matches是两个加密后的密码比较 */
/*		if (!passwordEncoder.matches(userParam.getOldPassword(), userParam.getNewPassword())){
			throw ExceptionUtil.commonException(ERROR_AUTHENTICATION_NEW_CONFIRM_PASSWORD_DIFF);
		}*/

		if (!userParam.getOldPassword().equals(userParam.getNewPassword())){
			throw ExceptionUtil.commonException(ERROR_AUTHENTICATION_NEW_CONFIRM_PASSWORD_DIFF);
		}
		/** 更新密码 */
		UpdateWrapper<User> updateWrapper = new UpdateWrapper<User>()
				.set("password",passwordEncoder.encode(userParam.getNewPassword()))
				.eq("id",user.getId());

/*		user.setPassword(passwordEncoder.encode(userParam.getNewPassword()));
		user.setUpdateTime(new Date());*/
		return this.update(updateWrapper);//SqlHelper.retBool(getBaseMapper().updateById(user));
	}

/*	@Override
	public Page<User> page(Page<User> page, Wrapper<UserView> queryWrapper) {
		return super.page(page,queryWrapper);
	}*/

	@Override
	public User getOne(Wrapper<User> queryWrapper, boolean throwEx){
		return super.getOne(queryWrapper,throwEx);
	}

	/**
	 * 取用户的单位信息
	 * @param userList
	 */
	private List<User> getExtentProp(List<User> userList){
		for(User u : userList){
			if (u.getOrgId() != null){
				u.setPassword(null);
			}
		}
/*
		* 单位
		List<Long> ids = new ArrayList<Long>();
		for(User u : userList){
			if (u.getOrgId() != null){
				ids.add(u.getOrgId() );
			}
		}
		if (ids.size() > 0){
			List<Organization>  list = organizationMapper.selectBatchIds(ids);
			for (Organization o : list){
				for(User origin : userList){
					if (o.getId().equals(origin.getOrgId())){
						origin.setOrgCode(o.getCode());
						origin.setOrgName(o.getName());
						origin.setOrgPath(o.getPath());
						origin.setOrganization(o);
					}
				}
			}
		}*/

		return userList;
	}

	@Override
	public UserBean getOneInfo(Wrapper<UserParam> queryWrapper, boolean throwEx){
		UserBean userBean = super.getOneInfo(queryWrapper,throwEx);
		if (userBean != null){userBean.setPassword(null);}
		return userBean;
	}

	@Override
	public List<UserBean> listInfo(Wrapper<UserParam> queryWrapper){
		List<UserBean> list = super.listInfo(queryWrapper);
		for(UserBean userBean : list ){
			userBean.setPassword(null);
		}
		return list;
	}

	@Override
	public Page<UserBean> pageInfo(Page<UserParam> page , Wrapper<UserParam> queryWrapper){
		Page<UserBean> page1 = super.pageInfo(page,queryWrapper);
		for(UserBean bean : page1.getRecords()){
			bean.setPassword(null);
		}
		return page1;
	}

	@Override
	public User getFromCache(String code){
		return (User)sysCache.hget(Constant.CACHE_KEY_USERS,code);
	}

	@Override
	public User getFromCacheByLoginName(String loginName){
		String code = (String)sysCache.hget(Constant.CACHE_KEY_USERS_BY_LOGINNAME,loginName);
		if (StringUtils.isEmpty(code)) return null;
		return (User)sysCache.hget(Constant.CACHE_KEY_USERS_BY_LOGINNAME,code);
	}


	@Override
	public void saveAllToCache() {
		sysCache.del(Constant.CACHE_KEY_USERS);
		sysCache.del(Constant.CACHE_KEY_USERS_BY_LOGINNAME);
		List<User> list = super.list();
		for(User user:list){
			this.saveToCache(user);
		}
	}
	@Override
	public void removeFromCache(String code){
		User user = getFromCache(code);
		if (user != null){
			sysCache.hdel(Constant.CACHE_KEY_USERS_BY_LOGINNAME, user.getLoginName());
			sysCache.hdel(Constant.CACHE_KEY_USERS, code);
		}
	}

	@Override
	public List<User> getAllFromCache() {
		List<User> list = new ArrayList<>();
		Map<Object,Object> map = sysCache.hmget(Constant.CACHE_KEY_USERS);
		if (map != null){
			for(Map.Entry<Object,Object> item: map.entrySet()){
				list.add((User) item.getValue());
			}}
		return list;
	}

	@Override
	public void saveToCache(User user) {
		sysCache.hset(Constant.CACHE_KEY_USERS, user.getCode(), user);
		sysCache.hset(Constant.CACHE_KEY_USERS_BY_LOGINNAME,user.getLoginName(),user.getCode());
	}
}
